<?php

class Com_Basil_DynamicData_ReferenceTableCollection extends Com_Basil_DynamicData_Collection {

	private $MAXROWS = 100;
	private $referenceKey;
	private $lastLoadedReferenceKey;
	private $currentIdx;
	private $hasNextRow = true;
	private $buffer;
	private $toBeRemoved;
	private $hbaseclient;
	
	public function __construct($jsonObj) {
		if (!isset($jsonObj['referenceKey'])) {
			$jsonObj['referenceKey'] = Com_Basil_DynamicData_Object::generateRandomKey();
		}
		$this->referenceKey = $jsonObj['referenceKey'];
		$this->currentIdx = 0;
		$this->buffer = array();
		$front = Zend_Controller_Front::getInstance();
		$this->hbaseclient = $front->getParam('bootstrap')->getResource('hbaseClient');
		
	}
	
	public function hasNext() {
		if (!$this->hasNextRow) {			
			return false;
		}
		
		//check now
		if ($this->currentIdx >= count($this->buffer))  {
			$this->loadMoreRows();
		}
		
		if ($this->currentIdx >= count($this->buffer))  {
			$this->hasNextRow = false;
		}
		return $this->hasNextRow;
	}
	
	private function loadMoreRows() {		
		$rows = $this->hbaseclient->getRows('reference-table',$this->referenceKey.'-*', $this->MAXROWS, $this->lastLoadedReferenceKey);				
		foreach ($rows as $row) {
			$columns = $row->toMap();
			if (isset($columns['reference:key'])) {
				$this->buffer[] = array(0 => $row->key, 1 =>$columns['reference:key']);
				$this->lastLoadedReferenceKey = $row->key;
			}
		}
	}
		
 	public function next() {
 		if (!$this->hasNext()) {
 			return null;
 		}
 		return $this->buffer[$this->currentIdx++][1];
 	}
 	
 	public function reset() {
 		$this->currentIdx = 0;
 	}
 	
 	public function addToCollection($object) {
 		if (!is_a($object, 'Com_Basil_DynamicData_Object')) {
 			$objectKey = $object;
 		} else {
 			$objectKey = $object->getKey();
 		} 		
 		$this->buffer[] = array(0=>'', 1=> $objectKey);	
 	}
 	public function removeFromCollection($object) {
 		//unfortunately we have to go through the array, i think
 		if (!is_a($object, 'Com_Basil_DynamicData_Object')) {
 			$objectKey = $object;
 		} else {
 			$objectKey = $object->getKey();
 		} 		 		
 		foreach($this->buffer as $key => $value) {
 			if ($value[1] == $objectKey) {
 				unset($this->buffer[$key]);	
 				$this->toBeRemoved[] = $value[0];
 			}
 		}
 		//re-index
 		$this->buffer = array_values($this->buffer);
 		$this->currentIdx = 0;
 	}
 	
 	public function store() {
 		$jsonObj = array('type'=>'reference', 'referenceKey'=>$this->referenceKey);
 		$rows = array();
 		foreach($this->buffer as $key => $value) {
 			if ($value[0] == '') {
 				// need to add
 				$cols[] = new Com_Basil_HBase_Data_Column('reference:key', $value[1]);
 				$newReferenceKey = $this->referenceKey.'-'.Com_Basil_DynamicData_Object::generateRandomKey();
 				$row = new Com_Basil_HBase_Data_Row($newReferenceKey, $cols);
 				$rows[] = $row;
 			}
 		}
 		if (count($rows) > 0) { 
 			$this->hbaseclient->insertUpdateRow('reference-table',$rows); 			
 		}
 		if (count($this->toBeRemoved)) {
 			$rows = array();
 			foreach($this->toBeRemoved as $removeRow) {
 				$row = new Com_Basil_HBase_Data_Row($removeRow, array());
 				$rows[] = $row;
 			}
 			$this->hbaseclient->deleteRows('reference-table',$rows);
 		}
 		return Zend_Json::encode($jsonObj);	
 	}
	
}

?>